(function($){
    $.fn.validateBox = function(options){
        var defaults = {
            delay: 0,
            width: 300,
            minLength: 0,
            source:[],
            onChangeValue: null,
            warningOnChange: false,
            valueBeforeLabel: false,
            disableValidate: false,
            warningTitle: "Cảnh báo",
            size: 8,
            warningMessage: "Bạn đang thay đổi dữ liệu, bạn có đồng ý không?",
            useDropDown: true,
            change: function(){},
            select: function(){},
            open : function(){},
            close: function(){}
        };
        var opt = $.extend(defaults, options);
        var $this = this;
        function validateboxblur(inputbox){
            if(opt.disableValidate)
                return;
            if(!$(inputbox).data( "autocomplete" ))
                return;
            if(!$.isArray(opt.source))
                return;
            var lastvalue = $(inputbox).data("autocomplete").previous;
            if(lastvalue == null)
                lastvalue = "";
            var curvalue = inputbox.value.toUpperCase();
            if(curvalue == lastvalue.toUpperCase()){
                inputbox.value = lastvalue;
                return;
            }
            var i = 0;

            for(; i < opt.source.length; i++){
                if(opt.source[i].value == curvalue){
                    break;
                }
            }
            if(i == opt.source.length)
            {
                inputbox.value = "";
                return;
            }
            //cap nhat lai gia tri value
            inputbox.value = opt.source[i].value;

            if(opt.onChangeValue != null &&  opt.onChangeValue instanceof Function){
                if(lastvalue.length > 0 && opt.warningOnChange == true){
                    if($("#validatebox-warning-change-value").length == 0){
                        var message;
                        if(opt.warningMessage instanceof jQuery){
                            message = $($('<div></div>').html(opt.warningMessage.clone())).html();
                        } else if(typeof opt.warningMessage === 'object')
                            message = $($('<div></div>').html($(opt.warningMessage).clone())).html();
                        else message = '<div style="font-size: 16px; color:red; font-weight: bold;">' + opt.warningMessage + "</div>";
                        $('<div id="validatebox-warning-change-value" style="display: none;" title="' + opt.warningTitle + '">' + message + '</div>').appendTo("body");
                    }
                    makeConfirmYesNo("#validatebox-warning-change-value",function(){
                        opt.onChangeValue();
                        $(inputbox).attr("lastvalue", inputbox.value);
                    }, function(){
                        inputbox.value = lastvalue;
                    });
                }else{
                    opt.onChangeValue();
                }
            }
        }

        var instance = this;
        this.setOption = function setOption(key, value){
            if(instance.data("autocomplete")){
                if ( key === "source" ) {
                    opt.source = value;
                }
                instance.data("autocomplete")._setOption(key, value);
            }
        }
        this.each(function(){
            var $this = this;
            $(this).autocomplete({
                delay: 0,
                source: opt.source,
                minLength: opt.minLength,
                width:opt.width,
                size:opt.size,
                change: function() {
                    validateboxblur($this);
                    opt.change();
                },
                select: function(event, item){
                    $this.value = item.item.value;
                    $this.blur();
                    validateboxblur($this);
                    opt.select();
                },
                open: function(){
                    $this.opening = true;
                    opt.open();
                },
                close: function(){
                    $this.opening = false;
                    opt.close();
                }
            }).focus(function(){
                this.select();
            }).blur(function(){
                validateboxblur($this);
            }).data("validatebox", instance);
            if(opt.useDropDown){
                var $$this = $($this);
                $( "<button>&nbsp;</button>" ).attr( "tabIndex", -1 ).attr( "title", "Hiển thị tất cả" )
                .insertAfter( $$this ).button({
                    icons: {
                        primary: "ui-icon-triangle-1-s"
                    },
                    text: false
                })
                .removeClass( "ui-corner-all" )
                .addClass( "ui-corner-right ui-button-icon" )
                .click(function() {
                    // close if already visible
                    if ( $$this.autocomplete( "widget" ).is( ":visible" ) ) {
                        $$this.autocomplete( "close" );
                        return;
                    }

                    // pass empty string as value to search for, displaying all results
                    $$this.autocomplete( "search", "" );
                    $$this.focus();
                }).css("width", "24px").css("height", ($$this.outerHeight(true) < 10? 22:$$this.outerHeight(true)) + "px");
            }
        });
        if(!this.data( "autocomplete" ))
            return;

        if(!opt.valueBeforeLabel){
            this.data( "autocomplete" )._renderItem = function(ul, item){
                var li = $( "<li></li>" )
                .data( "item.autocomplete", item );
                if(item.label && item.label != item.value){
                    li.append( $( "<a><table width='100%'><tr><td align='left' class='label-item'>" + item.label + "</td><td align='right' class='value-item'>" + item.value + "</td></tr></table></a>") );
                }
                else li.append( $( "<a>" + item.value + "</a>") );
                li.appendTo( ul );
                return li;
            }
        } else {
            this.data( "autocomplete" )._renderItem = function(ul, item){
                var li = $( "<li></li>" )
                .data( "item.autocomplete", item );
                if(item.label && item.label != item.value){
                    li.append( $( "<a><table width='100%'><tr><td align='left' class='value-item'>" + item.value + "</td><td align='right' class='label-item'>" + item.label + "</td></tr></table></a>") );
                }
                else {
                    li.append( $( "<a>" + item.value + "</a>") );
                }
                li.appendTo( ul );
                return li;
            }
        }
        this.data("autocomplete")._resizeMenu = function() {
            var ul = this.menu.element;
            ul.outerWidth( Math.max(
                //Hienforis them dong nay
                this.options.width ? this.options.width: ul.width( "" ).outerWidth(),
                //Hienforis bo dong nay ul.width( "" ).outerWidth(),
                this.element.outerWidth()
                ) );
            //Hienforis them vo doan nay luc 19/11/2010 16:40
            var li = $("li", ul);
            if(this.options.size && this.options.size < li.length){
                ul.css("overflow", "auto").height(this.options.size* li.outerHeight());
                if($.browser.msie){
                    li.width(li.width() - 20);
                }
            }
            else {
                ul.height( "" );
            }
        // ket thuc them vo luc 19/11/2010 16:40
        }
        return this;
    };
    $.extend( $.ui.autocomplete, {
        filter: function(array, term) {
            var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
            return $.grep( array, function(value) {
                return matcher.test( value.value || value.label || value );
            });
        }
    });
})(jQuery);